/*
 * Description: 性能相关配置文件读取工具类
 */
#ifndef PERF_CONFIG_FACTORY_H
#define PERF_CONFIG_FACTORY_H

#include "cJSON.h"
#include <memory>
#include <mutex>
#include "singleton.h"
#include <string>
#include <vector>
#include <unordered_map>

namespace PERF {

class AllowedSite {
public:
    std::string domain;
    std::vector<std::string> protocols;
};

class Registry {
public:
    std::string key;
    std::string item;
};
class Autorun {
public:
    std::string appName;
    std::string moduleName;
    bool shouldRemove{ false };
    std::unordered_map<std::string, std::vector<Registry>> registry;
    std::vector<std::string> paths;
    std::vector<Registry> services;
    std::vector<std::string> scheduledTasks;
};

class PerfConfig {
public:
    std::vector<AllowedSite> allowedSites;
    std::unordered_map<std::string, Autorun> moduleNameToAutoruns;
};

class PerfConfigFactory {
public:
    std::shared_ptr<PerfConfig> GetConfig();
    void ClearConfig();
    std::shared_ptr<PerfConfig> ParseConfig(const std::string &json);

private:
    std::string ReadConfigStrFromFile();
    bool ReadAllowedSites(cJSON *root, std::shared_ptr<PerfConfig> &config);
    bool ReadAutoruns(cJSON *root, std::shared_ptr<PerfConfig> &config);
    bool ReadSite(cJSON *siteJsonObject, AllowedSite &site);
    bool ReadAutorun(cJSON *autorunObject, Autorun &autorun);
    bool ReadRegistry(cJSON *registryObject, Autorun &autorun);
    bool ReadPaths(cJSON *pathsJsonArr, Autorun &autorun);
    bool ReadServices(cJSON *servicesJsonArr, Autorun &autorun);
    bool ReadScheduledTasks(cJSON *scheduledTasksJsonArr, Autorun &autorun);
    std::string GetJsonStr(cJSON *jsonStr);

    std::shared_ptr<PerfConfig> config{ nullptr };
    std::mutex perfConfigMutex;
    const std::string PERF_CONFIG_FILE_PATH = "C:\\ProgramData\\performance\\perf.cfg";
};

#define PERF_CONFIG_FACTORY SingletonNew<PERF::PerfConfigFactory>::GetInstance()

}  // namespace PERF

#endif